<?php
/*******************************************************************************

    FinalsClub.org is a platform for students and faculty to collaborate
    and share their knowledge with the world.

    Copyright (C) 2009  Andrew Magliozzi

    This file is a part of FinalsClub.org.

    FinalsClub.org is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    To contact FinalsClub.org, send an email to info@finalsclub.org, or
    send mail to Finals Club, c/o Veritas Tutors, 1132 Massachusetts Avenue,
    Cambridge, MA 02138.

*******************************************************************************/

/**
 * invitations actions.
 *
 * @package    FinalsClub
 * @subpackage invitations
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 12474 2008-10-31 10:41:27Z fabien $
 */
class invitationsActions extends sfActions
{
	
  public function executeNew(sfWebRequest $request)
  {
    $this->form = new InvitationForm();
  }

  public function executeCreate(sfWebRequest $request)
  {
  	// if this request isnt a post redirect to 404
  	$this->forward404Unless($request->isMethod('post'));
    $invitation = new Invitation();
    $this->form = new InvitationForm();
    $user = new User();
    $user = UserPeer::retrieveById($this->getUser()->getId());
    
    // bind form values
    $this->form->bind($request->getParameter('invitation'));
    
    // validators for this form check for a valid e-mail address that has not been registered
    if($this->form->isValid())	{	
    	$email_address = $request->getParameter('invitation[email]');
    	$invite_message = $request->getParameter('invitation[message]');
		$this->mailed_to = $email_address;		// for the createSuccess template
    	
		// our token is the 11 characters after the first four of a md5 hash of the current unix timestamp
    	$token = substr(md5(time()),4,11);
    	
    	// set the fields for the invitation object
    	$invitation->setEmail($email_address);		// email address of the recipient
    	$invitation->setToken($token);				// set the token for the invite
    	$invitation->setMessage($invite_message);			// personal message added by the user
    	$invitation->setUserId($this->getUser()->getId());		// id of the user sending the invite
    	$invitation->setStatus(InvitationPeer::PENDING);	// set the status to pending
    	$invitation->save();

		// generate the full url for the accept_invite route with the invitation id and token as parameters which will be passed to our HTML and PlainText e-mail body partials 
    	$invite_url = $this->generateUrl('accept_invite', array('id'=>$invitation->getId(), 'token'=>$invitation->getToken()), true);

    	// retrieve the smtp server from the app.yml file
		$smtp_server = sfConfig::get('app_smtp_server');
		$smtp_user = sfConfig::get('app_smtp_user');
		$smtp_password = sfConfig::get('app_smtp_password');
		try
		{
		  // Create the mailer object
		  $connection = new Swift_Connection_SMTP($smtp_server, 465, Swift_Connection_SMTP::ENC_SSL);
		  $connection->setUsername($smtp_user);
		  $connection->setPassword($smtp_password);
		  $mailer = new Swift($connection);  
		  
		  // Subject line
		  $message = new Swift_Message('You have been invited to FinalsClub');

		  // Render message parts
		  $mailContext = array('invite_url'=>$invite_url, 'from'=>$user->getFullName(), 'message'=>$invite_message);	// to be passed as a parameter to the partials
		  $message->attach(new Swift_Message_Part($this->getPartial('invitationHtml', $mailContext), 'text/html'));		// HTML e-mail body
		  $message->attach(new Swift_Message_Part($this->getPartial('invitationPlain', $mailContext), 'text/plain'));	// Plaintext e-mail body
		  
		  // Set 'To' and 'From' fields
		  $mailer->send($message, $email_address, $smtp_user);
		  $mailer->disconnect();
		}
		catch (Exception $e)
		{
		  	$this->logMessage($e->getMessage(), 'crit');	// Log the exception as critical
		  	$this->getUser()->setFlash('warning', 'Failed to initialize mailer!');		// alert the user e-mailing failed
		}
    }
    else {
    	if($this->getUser()->hasFlash('ajax'))		// determine which action to load the template of
    		if($this->getUser()->getFlash('ajax'))
    			$this->setTemplate('loadform'); // if the form is invalid let them try again
    		else
    			$this->setTemplate('new');	// if the form is invalid let them try again
    	else
    		$this->setTemplate('new'); // if the form is invalid let them try again
    }
  }

  public function executeAccept(sfWebRequest $request) 
  {
    $invitation = new Invitation();

    // get the invite record id and the token from the request parameters
	$invite_id = $request->getParameter('id');
	$token = $request->getParameter('token');
  			
  	// make sure an invitation with the id == $invite_id exists
  	$invitation = InvitationPeer::retrieveById($invite_id);
  	if(($invitation instanceOf Invitation)) {		// the invitation record was found
  		// now we make sure the invitation has not already been accepted (status is PENDING)
  		$status = $invitation->getStatus();
  		if($status == InvitationPeer::PENDING) {
  			$stored_token = $invitation->getToken();	// the status is pending so now we check the tokens
    		if(strcmp($token, $stored_token) === 0) {	// stored and passed tokens are identical strings
    			// this flash variable lets the user registration know to update the recipient_id of the invitation object 
  				$this->getUser()->setFlash('invited', true);
  				// put the email address in a flash variable to populate the registration form
  				$this->getUser()->setFlash('email', $invitation->getEmail());
  				// send the user to register
				$this->forward('users', 'new');
    		}
    		else {	// the tokens didn't match
    			$this->form = new UserForm();
    			$this->getUser()->setFlash('warning', 'Invalid invitation link!');
    			$this->setTemplate('new', 'users');
    		}
  		}
  		else {	// invite has already been accepted
  			$this->form = new UserForm();
    		$this->getUser()->setFlash('warning', 'That invitation has already been accepted!');
    		$this->setTemplate('new', 'users');
  		}
  	}
    else {	// invitation id was invalid - no record was found
  		$this->form = new UserForm();
    	$this->getUser()->setFlash('warning', 'Incomplete request!');
    	$this->setTemplate('new', 'users');
  	}
  }
  
  public function executeLoadform() {
  	$this->form = new InvitationForm();
  	$this->getUser()->setFlash('ajax', true);	// tells the create action which template to load on a form error
  }

}
